package com.xianshijian.oauth.server.service;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate;

import com.xianshijian.oauth.common.entity.OAuth;
import com.xianshijian.oauth.common.entity.OAuthResult;
import com.xianshijian.oauth.server.dao.ThirdPartyDao;
import com.xianshijian.oauth.server.dto.Parameter;
import com.xianshijian.oauth.server.entity.ThirdParty;

/**
 * 授权Service
 * 
 * @author lzj
 *
 */
@Service
public class OAuthService {
	private static final Logger LOG = LoggerFactory.getLogger(OAuthService.class);

	@Autowired
	private ThirdPartyDao thirdPartyDao;

	@Value("${oauth.userinfo.url}")
	private String userInfoUrl;

	@Value("${jianke.userinfo.url}")
	private String jiankeUserUrl;

	/**
	 * 添加access_token
	 * @param authorizationCode
	 * @param accessToken
	 * @return
	 */
	public boolean addAccessToken(String authorizationCode, String accessToken) {
		RestTemplate restTemplate = new RestTemplate();
		OAuthResult oAuthResult = restTemplate.getForObject(
				userInfoUrl + "addAccessToken/{authorizationCode}/{accessToken}", OAuthResult.class,
				authorizationCode, accessToken);
		if (oAuthResult.getStatus() == OAuth.StatusCode.OK) {
			return true;
		}
		return false;
	}

	/**
	 * 添加授权码
	 * @param thirdPartyId
	 * @param authorizationCode
	 * @param sjkSessionId
	 * @return
	 */
	public boolean addAuthCode(String thirdPartyId, String authorizationCode, String sjkSessionId) {
		ThirdParty thirdParty = thirdPartyDao.findByThirdPartyId(thirdPartyId);
		RestTemplate restTemplate = new RestTemplate();
		String accountId = restTemplate.getForObject(jiankeUserUrl + "oauth2/getAccoutId/{sjkSessionId}",
				String.class, sjkSessionId);
		if (StringUtils.isNotBlank(accountId)) {
			OAuthResult oAuthResult = restTemplate.getForObject(
					userInfoUrl + "addAuthCode/{accountId}/{serviceId}/{authorizationCode}", OAuthResult.class,
					accountId, thirdParty.getId(), authorizationCode);
			if (oAuthResult.getStatus() == OAuth.StatusCode.OK) {
				return true;
			}
		}
		return false;

	}

	/**
	 * 验证thirdPartyId
	 * 
	 * @param thirdPartyId
	 * @return
	 */
	public boolean checkThirdPartyId(String thirdPartyId) {
		return thirdPartyDao.findByThirdPartyId(thirdPartyId) != null;
	}

	/**
	 * 验证sign
	 * @param thirdPartyId
	 * @param sign
	 * @param redirectURL
	 * @param code
	 * @param scope
	 * @return
	 */
	public boolean checkThirdPartyIdThirdPartySecret(String thirdPartyId, String sign, String redirectURL, String code,
			String scope) {
		ThirdParty thirdParty = thirdPartyDao.findByThirdPartyId(thirdPartyId);
		if (thirdParty != null) {
			String thirdPartySecret = thirdParty.getThirdPartySecret();

			// 放入参数
			List<Parameter> paramList = new ArrayList<Parameter>();
			paramList.add(new Parameter("redirect_url", redirectURL));
			paramList.add(new Parameter("third_party_id", thirdPartyId));
			paramList.add(new Parameter("scope", scope));
			paramList.add(new Parameter("code", code));

			String urlParam = "";
			// 排序参数
			paramList.sort((a, b) -> a.getKey().compareTo(b.getKey()));
			for (Parameter parameter : paramList) {
				// 仅在高版本jdk中编译器自动优化字符串+为StringBuilder, 低版本请自行append
				urlParam += "&" + parameter.getKey() + "=" + parameter.getValue();
			}

			// 签名得到sign
			String mySign = DigestUtils.md5DigestAsHex((urlParam + thirdPartySecret).getBytes());
			System.out.println(mySign);
			System.out.println(sign);
			if (mySign.equals(sign)) {
				return true;
			} else {
				LOG.error("mySign : {}, sign : {}", mySign, sign);
				LOG.error(urlParam + thirdPartySecret);
				throw new RuntimeException("签名校验失败");
			}
		}
		return false;
	}

	/**
	 * 返回过期时间,默认为2天，单位为毫秒
	 * 
	 * @return
	 */
	public long getExpireIn() {
		return 172800000;
	}

	/**
	 * 根据cookie中的sessionId_sjk验证用户是否登陆
	 * 
	 * @return
	 */
	public String checkUserLogin(String sjkSessionId) {
		RestTemplate restTemplate = new RestTemplate();
		return restTemplate.getForObject(jiankeUserUrl + "oauth2/checkUserLogin/{sjkSessionId}", String.class,
				sjkSessionId);

	}

}
